import { reactive, markRaw, computed, createVNode, readonly, watch, toRaw } from "vue";

import { TabItemClass } from '@/model/AppModel';
import pages, { Page } from "@/router/pages";
import HomePage from "@/views/pages/Home";

/**
 * 首页  
 */
let homeTabItem = new TabItemClass({
  title: pages[0].title,
  icon: pages[0].icon,
  name: pages[0].name,
  pageComponent: markRaw(HomePage),
  // pageComponent: markRaw(DyVideo),
  hiddenClose: true
})

const state = reactive<{
  /**
  * 表示当前自定义路由信息
  */
  tabList: TabItemClass[],

  /**
   * 全部页面组件的 实例
   */
  tabViewList: { [key: string]: any },

  /**
   * 当前选中的路由
   */
  selectTabId: string,
}>({
  tabList: [homeTabItem],
  tabViewList: {},
  selectTabId: homeTabItem.id,
})

/**
 * state只能是只读的
 */
export const tabsState = readonly(state);


/**
 * 更新数据
 * @param value 数据
 */
export const setTabList = function (value: TabItemClass) {
  state.tabList.push(value)
}

/**
 * 缓存路由的name
 */
export const tabCacheNameList = computed<string[]>(() => {
  return state.tabList.map((item: any) => {
    return item.name
  })
})

/**
* 返回当前选中的路由
*/
export const selectTabItem = computed<TabItemClass | false>(() => {
  let selectTabId = state.selectTabId;
  let tabList = state.tabList;
  return tabList.find(
    (item: TabItemClass) => {
      return item.id == selectTabId;
    }
  ) || false;
})

/**
 * 要想在外部修改state中数据,
 * 只能通过appAction
 */
export const tabsAction = {
  /**
  * 添加组件实例
  */
  setTabViewList(value: any) {
    state.tabViewList = value;
  },
  /**
   * 选中一个页签
   */
  selectTab(id: string) {
    if (!id) {
      console.error(`selectTab：请输入选中页签的 index 值`);
      return;
    }
    state.selectTabId = id;
  },
  /**
   * 判断是否存在某个id的页签
   */
  isTab(id: string): boolean {
    //当存在id的时候 , 需要进行判断 , 当前tab页签是否已经被添加上了
    return state.tabList.findIndex((item: TabItemClass) => {
      return item.id == id;
    }) >= 0
  },
  /**
   * 删除一个 页签
   * @param id 删除的标签id
   */
  removeTab(id: string) {
    if (!id) {
      console.error(`removeTab：请输入选中页签的id`);
      return;
    }
    let index = state.tabList.findIndex((item: any) => {
      return item.id == id
    })
    if (index < 0) {
      console.error(`removeTab：[${id}]页签不存在`);
      return;
    }

    if (id == state.selectTabId) {
      //表示当前删除页签 为 当前页面
      //我们 就展示 他后一个页面
      if (index >= state.tabList.length - 1) {
        //表示当前页面为最后一个页签
        //我们就展示前一个页面
        //因为这个 第一个页签的首页 是没法删除的 ， 所以这里一定是大于0的，就不判断
        tabsAction.selectTab(state.tabList[index - 1].id)
      } else {
        //如果当前页面不是最后一个页签
        //就展示他后面的一个页签
        tabsAction.selectTab(state.tabList[index + 1].id)
      }
    }
    //删除 tab页签中的数据
    state.tabList.splice(index, 1);
  },
  /**
   * 删除全部tab页签
   */
  removeAllTab() {
    if (state.tabList.length > 1) {
      //删除 tab页签中的数据
      state.tabList.splice(1);
      tabsAction.selectTab(state.tabList[0].id)
    }
  },
  /**
 * 关闭其他页面
 */
  removeOtherTab(id: string) {
    if (!id) {
      console.error(`removeTab：请输入选中页签的id`);
      return;
    }
    let index = state.tabList.findIndex((item: any) => {
      return item.id == id
    })

    if (index < 0) {
      return;
    }

    if (index < state.tabList.length - 1) {
      //如果不是最后一个页签 , 我们就删除它后面的页签
      state.tabList.splice(index + 1);
    }

    if (index > 1) {
      //表示不是第二个页签 或者第一个页签 , 
      //因为首页一定是第一个 , 所以不是第二个表示再首页和这个页签之间还有其他页签
      //我们就删除之间的页签
      state.tabList.splice(1, index - 1);
    }
  }
}

/**
 * 新增一个页签
 * @param pageName 前端页面名称
 * @param param1 
 * @param data 这个是表示想页面注入的数据
 */
export const addTab = function (pageName: string, {
  //自定义标题
  title = "",
  //这个是图标
  icon = "",
  //表示将一个特定id的页面 调整为 我们想要添加的页面
  id = "",
} = {}, data = {}): Promise<TabItemClass> {
  if (!pageName) {
    console.error(`addTab：pagename为必填参数`)
    return Promise.reject()
  }

  //这里需要根据name  获取到 应有的页面
  let page: Page | undefined = pages.find((item) => {
    return item.name == pageName;
  })

  if (!page) {
    console.error(`addTab：[${pageName}]页面不存在`)
    return Promise.reject()
  }

  //创建页签
  let tabItem = reactive(new TabItemClass({
    title: title || page.title,
    name: page.name,
    icon: icon || page.icon,
    pageComponent: null,
  }))


  if (id) {
    //存在需要替换的id页签的时候

    let findIndex = state.tabList.findIndex(item => {
      return item.id == id;
    })
    if (findIndex >= 0) {
      //存在就替换
      state.tabList.splice(findIndex, 1, tabItem)
    } else {
      //不存在的话我们就新增
      state.tabList.push(tabItem);
    }
  } else {
    //没有id 就正常添加
    //首先将页面加载进去
    state.tabList.push(tabItem)
  }
  //选中当前页面
  tabsAction.selectTab(tabItem.id);

  //获取页面
  page.component()
    .then((res: any) => {
      let vnode = createVNode(res.default, {
        appTabItem: tabItem,
        appData: data
      });
      if (tabItem) tabItem.pageComponent = vnode;
    })

  return Promise.resolve(tabItem);
}


/**
 * ================================
 *  tabsStore 的初始化
 * ================================
 */

/**
 * 非开发模式,才会计算
 */
/**
 * 将数据添加到会话中进行保存
 */
// const STORAGE_KEY = '--TABS-STORAGE--';

// let sessionStorageData = JSON.parse(window.sessionStorage.getItem(STORAGE_KEY) || "{}");
// for (let x in sessionStorageData) {
//   if ([""].indexOf(x) < 0 && typeof (state as any)[x] != "undefined") {
//     (state as any)[x] = sessionStorageData[x];
//   }
// }

// watch(state, () => {
//   let rawData = toRaw(state);
//   rawData.tabList
//   window.sessionStorage.setItem(STORAGE_KEY, JSON.stringify(rawData))
// })